package gcontent.filter;

import java.util.HashMap;
import java.util.Vector;

import org.apache.log4j.Logger;

import gcontent.entities.Content;
import gcontent.entities.Site;
import gcontent.filter.error.FilterEx;

public class FilterChain {
	
	public static final int DEF_MAX_FILTERS = 50;
	public static final String DEF_TYPE = "none";
	
	public static Logger log = Logger.getLogger(FilterChain.class);
	
	
	public static int validateFilter(Filter filter, Object cont)
	{
		int ret;
		
		if(cont instanceof Content) {
			ret = filter.check((Content)cont);
		} else if(cont instanceof Site) {
			ret = filter.check((Site)cont);
		} else 
			ret = Filter.STATUS_EXIT;
		
		return ret;
	}
	
	public static void setFilter(HashMap<String, Vector<Filter>> filters, Filter filter) throws FilterEx
	{
		setFilter(filters, filter, DEF_MAX_FILTERS);
	}
	
	public static void setFilter(HashMap<String, Vector<Filter>> filters, Filter filter, int max_filter) throws FilterEx
	{
		Vector<Filter> v_filter;
		int order;
		
		order = filter.getOrder();
		if(order <= 0 || order > max_filter)
			throw new FilterEx("invalid order index for filter (" + filter.getType() + ")");
				
		v_filter = filters.get(filter.getType());
		if(v_filter == null) {
			v_filter = new Vector<Filter>(max_filter);
			for(int i = 0; i < max_filter; i++)
				v_filter.add(new Filter());

			v_filter.set(order - 1, filter);
		
			filters.put(filter.getType(), v_filter);
		} else {						
			if(v_filter.get(order - 1).getOrder() != -1)
				throw new FilterEx("already exist a filter on index " + order);
			
			v_filter.set(order - 1, filter);			
		}
	}
	
	public static boolean passFilters(HashMap<String, Vector<Filter>> filters, Object cont, String type, boolean def_action)
	{
		Vector<Filter> v_filter;
		int status;
	
		v_filter = filters.get(type);
		if(v_filter == null || v_filter.size() == 0)
			return def_action;
		
		status = Filter.STATUS_FAILED;
		for(int i = 0; i < v_filter.size(); i++) {
			Filter filter;
			
			filter = v_filter.get(i);
			if(filter == null)
				continue;
			
			status = validateFilter(filter, cont);
			/* reverse result */
			if(filter.isReversed() == true) {
				if((status & Filter.STATUS_OK) != 0) {
					status = status & ~Filter.STATUS_OK;
					status |= Filter.STATUS_FAILED;
				} else {
					status = status & ~Filter.STATUS_FAILED;
					status |= Filter.STATUS_OK;
				}
			}
			
			if((status & Filter.STATUS_EXIT) != 0)
				break;
		}
		
		return (status & Filter.STATUS_SUCCESS) != 0;
	}	
}
